<template>
  <!-- 断点续传 -->
  <a-spin :loading="loading" tip="上传中...">
    <div>

      <div class="upload-file w-full">
        <a-upload :custom-request="uploadFileHandler" :show-file-list="false" :multiple="props.multiple"
          :accept="props.accept" :disabled="isDisabled" :tip="props.tip" :draggable="props.draggable">
          <template #upload-button v-if="props.draggable">
            <slot name="customer">
              <div style="background-color: var(--color-fill-2); border: 1px dashed var(--color-fill-4)"
                class="rounded text-center p-7 w-full">
                <div>
                  <icon-upload class="text-5xl text-gray-400" />
                  <div class="text-red-600 font-bold">
                    {{ props.title }}
                  </div>
                  将文件拖到此处，或<span style="color: #3370ff">点击上传</span>
                </div>
              </div>
            </slot>
          </template>
        </a-upload>
      </div>
      <div  class="file-list mt-2" v-for="(file, idx) in showFileList" :key="idx">
        <a-tooltip content="点击文件名预览/下载" position="tr">
          <a v-if="file.path?.includes('width')" :href="file.path" class="file-name" target="_blank">{{ file.path }}</a>
          <a v-else-if="file.path?.includes('video')" :href="file.preview" class="file-name" target="_blank">{{ file.path }}</a>
          <a v-else :href="file.path" class="file-name" target="_blank">{{ file.path }}</a>
        </a-tooltip>

        <a-button type="text" size="small" @click="removeFile(idx)">
          <template #icon>
            <icon-delete />
          </template>
        </a-button>
      </div>
    </div>
  </a-spin>
</template>
<script setup>
import { ref, watch, computed } from 'vue'
import { isArray } from 'lodash'
import commonApi from '@/api/common'
import { Message } from '@arco-design/web-vue'
import axios from 'axios';
// 分块大小2MB
const chunkSize = 1024 * 1024 * 2;
const loading = ref(false)

const props = defineProps({
  modelValue: {
    type: [String, Number, Array],
    default: () => { },
  },
  showList: { type: Boolean, default: true },
  draggable: { type: Boolean, default: false },
  multiple: { type: Boolean, default: false },
  disabled: { type: Boolean, default: false },
  title: { type: String, default: '本地上传' },
  icon: { type: String, default: 'icon-plus' },
  size: { type: Number, default: 1024 * 1024 * 1024 },
  limit: { type: Number, default: 1 },
  mode: { type: String, default: 'system' },
  tip: { type: String, default: undefined },
  accept: { type: String, default: '*' },
})
const emit = defineEmits(['update:modelValue'])
const showFileList = ref([])
const signFile = ref()
const currentItem = ref({})

const isDisabled = computed(() => {
  if (props.disabled) {
    return true
  } else {
      if (showFileList.value.length == props.limit && showFileList.value.length != 0) { 
      return true
    }
    return false
  }
})
const uploadFileHandler = async (options) => {
  let isCheck = true
  const file = options.fileItem.file
  console.log('当前文件', file);
  if (file.size > props.size) {
    Message.warning(file.name + '超出文件大小限制')
    currentItem.value = {}
    isCheck = false
  }
  if ( props.limit > 0) {
    if (showFileList.value.length >= props.limit) {
      Message.warning('最多上传' + props.limit + '个文件')
      currentItem.value = {}
      isCheck = false
    }
  }

  if (isCheck) {
    let fileName = file.name;
    let fileSize = file.size || 0;
    let chunkTotals = Math.ceil(fileSize / chunkSize); 
    let isLastChunk = null;
    let isFirstUpload = null;
    if (chunkTotals > 0) {
      const { data } = await commonApi.getUploadToken({}) //获取token
      for (let chunkNumber = 0, start = 0; chunkNumber < chunkTotals; chunkNumber++, start += chunkSize) {
        loading.value = true
        let end = Math.min(fileSize, start + chunkSize);
        chunkNumber == 0 ? (isFirstUpload = 1) : (isFirstUpload = 0);
        if (Number(chunkNumber) + 1 == Number(chunkTotals)) {
          isLastChunk = 1;
        } else {
          isLastChunk = 0;
        }
        const files = file.slice(start, end);
        if (data) { 
          try {
          const result = await uploadFileToServer(
          files,
          fileName,
          fileSize,
          isLastChunk,
          isFirstUpload,
          chunkTotals,
          data//token    
        );
        console.log('result', result);
        if (result?.data?.data?.isLastChunk == 1) { 
          loading.value = false
          showFileList.value.push(result.data?.data)
          let files = []
          files = showFileList.value.map((item) => {
            return item['path']          
          })
          emit('update:modelValue', files)
          console.log('上传文件列表', showFileList.value);
        }
        } finally { 
          loading.value = false
        }
        }


      }
    }
    
  }
  }

const removeSignFile = () => {
  currentItem.value = {}
  signFile.value = undefined
  emit('update:modelValue', null)
}

const removeFile = (idx) => {
  showFileList.value.splice(idx, 1)
  let files = []
  files = showFileList.value.map((item) => {
    return item['path']
  })
  emit('update:modelValue', files)
}

const initData = async () => {
  console.log('111',props.modelValue);
    if (props.modelValue) {
      signFile.value = props.modelValue
      showFileList.value=[]
    if (props.modelValue && props.modelValue.length > 1) {
      props.modelValue?.forEach((itm, idx) => {
        currentItem.value.url = itm
        if (itm.includes('.m3u8')) {
          showFileList.value.push({ path: itm,preview:itm.replace('manifest/video.m3u8','watch') })
        } else { 
          showFileList.value.push({ path: itm })
        }
      })
    } else if(props.modelValue && props.modelValue.length == 1) { 
      props.modelValue?.forEach((itm, idx) => {
        currentItem.value.url = itm
        if (itm.includes('.m3u8')) {
          showFileList.value.push({ path: itm,preview:itm.replace('manifest/video.m3u8','watch') })
        } else { 
          showFileList.value.push({ path: itm })
        }
      })
    }
    console.log('222',showFileList.value);
  } else {
    removeSignFile()
  }
}

watch(
  () => props.modelValue,
  (val) => {
    initData()
  },
  {
    deep: true,
    immediate: true,
  }
)

/**
 * 将分块文件上传至服务器
 * @param file 上传的分块文件
 * @param chunks_num 当前是第几块
 * @param chunkTotal 文件分块的总数
 * @param fileName 文件名称
 * @param isLastChunk 是否最后一个块 0 不是 1 是
 * @param isFirstUpload 是否第一个块 0 不是 1 是
 */
const uploadFileToServer = async (
  file,
  fileName,
  totalSize,
  isLastChunk,
  isFirstUpload,
  chunkTotal,
  upload_token
) => {
  const form = new FormData();
  form.append("theFile", file);
  form.append("fileName", fileName);
  form.append("totalSize", totalSize);
  form.append("isLastChunk", isLastChunk);
  form.append("isFirstUpload", isFirstUpload);
  form.append("chunks_num", chunkTotal);
  // form.append("chunkNumber", chunkNumber);
  const result=  await  axios.post(import.meta.env.VITE_APP_BIG_FILE_URL, form, { headers: { 'Content-Type': 'multipart/form-data', 'Authorization': 'Bearer ' +upload_token }, timeout: 100000 })
  return  result  
}
</script>

<style lang="less" scoped>
.file-list {
  background-color: var(--color-primary-light-1);
  border-radius: 4px;
  height: 36px;
  padding: 0 5px;
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;

  .file-name {
    max-width: 90%;
    margin: 0 5px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    color: #165dff;
  }
}
</style>
